package com.jweb.framework.core.impl;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.jweb.framework.core.CoreRegistry;
import com.jweb.framework.core.CoreRuntimeException;
import com.jweb.framework.core.Interceptors;
import com.jweb.framework.core.ProcessExecutor;
import com.jweb.framework.core.Processing;

/**
 * 修改人： Thomas
 * 修改内容：新增 
 * 类说明：默认核心服务注册
 */
public class DefaultCoreRegistry implements CoreRegistry , ApplicationContextAware {
	
	private boolean notFoundFlag ;
	
	private boolean duplicateFlag ;
	
	private Map processMap ;
	
	private Map processExecutorMap ;
	
	private Map interceptorsMap ;
	
	protected ApplicationContext applicationContext;
	
	public DefaultCoreRegistry(){
		this.notFoundFlag = true ;
		this.duplicateFlag = true ;
		this.processMap = new ConcurrentHashMap();
		this.processExecutorMap = new ConcurrentHashMap();
		this.interceptorsMap = new ConcurrentHashMap();
	}
	
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
	{
		this.applicationContext = applicationContext;
	}
		
	/**
	 * @param notFoundFlag the notFoundFlag to set
	 */
	public void setNotFoundFlag(boolean notFoundFlag) {
		this.notFoundFlag = notFoundFlag;
	}

	/**
	 * @param duplicateFlag the duplicateFlag to set
	 */
	public void setDuplicateFlag(boolean duplicateFlag) {
		this.duplicateFlag = duplicateFlag;
	}

	/**
	 * findExecutor(String s)此方法用于DefaultDispatcher类中，因为DefaultDispatcher类只实现Dispatcher接口，无需要在此类中获取ApplicationContext
	 * 		这个类在 DefaultCoreRegistry类中获取，从而DefaultDispatcher类看起来非常简单。
	 * 	
	 * 	下面的findInterceptors(String s),findProcedure(String s)与findExecutor(String s)方法类似。
	 * 
	 */
	public ProcessExecutor findExecutor(String s) {
		
		ProcessExecutor processExecutor = (ProcessExecutor)processExecutorMap.get(s);
		if(processExecutor == null){
			try {
				processExecutor = applicationContext.getBean(s, ProcessExecutor.class);
			} catch(NoSuchBeanDefinitionException _ex) {
				// TODO: handle exception
			}
		}
		if(processExecutor == null && notFoundFlag){
			throw new CoreRuntimeException("JAVACO0013",new String[]{s},"not_process_template_found");
		}
		else
			return processExecutor ;
	}

	public Interceptors findInterceptors(String s) {
		
		Interceptors interceptors = (Interceptors) interceptorsMap.get(s);
		if(interceptors == null){
			try {
				interceptors = applicationContext.getBean(s, Interceptors.class);
			} catch(NoSuchBeanDefinitionException _ex) {
				// TODO: handle exception
			}
		}
		if(interceptors == null && notFoundFlag){
			throw new CoreRuntimeException("JAVACO0014", new String[]{s}, "not interceptors found");
		}
		else 
			return interceptors;
	}

	public Processing findProcedure(String s) {
		
		Processing processing = (Processing) processMap.get(s);
		if(processing == null){
			try {
				processing = applicationContext.getBean(s, Processing.class);
			} catch(NoSuchBeanDefinitionException _ex) {
				// TODO: handle exception
			}
		}
		if(processing == null && notFoundFlag){
			throw new CoreRuntimeException("JAVACO0015",new String[]{s},"not process found");
		}
		else 
			return processing;
	}

	public void register(Interceptors interceptors) {
		if(duplicateFlag && processMap.containsKey(interceptors.getName())){
			throw new CoreRuntimeException("JAVACO0016",new String[]{interceptors.getName()},"duplicated interceptors defined");
		}
		else{
			interceptorsMap.put(interceptors.getName(), interceptors);
		}
	}

	public void register(ProcessExecutor processexecutor) {
		if(duplicateFlag && processMap.containsKey(processexecutor.getName())){
			throw new CoreRuntimeException("JAVACO0017",new String[]{processexecutor.getName()},"duplicated process template defined");
		}
		else{
			processExecutorMap.put(processexecutor.getName(), processexecutor);
		}
	}

	public void register(Processing processing) {
		if(duplicateFlag && processMap.containsKey(processing.getName())){
			throw new CoreRuntimeException("JAVACO0018",new String[]{processing.getName()},"duplicated process defined");
		}
		else{
			processMap.put(processing.getName(), processing);
		}
	}

	public void unregister(Interceptors interceptors) {
		interceptorsMap.remove(interceptors.getName());
	}

	public void unregister(ProcessExecutor processexecutor) {
		processExecutorMap.remove(processexecutor.getName());
	}

	public void unregister(Processing processing) {
		processMap.remove(processing.getName());
	}
}
